package com.pz.chat.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pz.chat.constant.MessageTypeEnum;
import com.pz.chat.constant.RabbitMqConstant;
import com.pz.chat.dao.ChatMessageDao;
import com.pz.chat.entity.ChatMessageEntity;
import com.pz.chat.entity.MemberEntity;
import com.pz.chat.entity.resultmap.ChatMessageResultMap;
import com.pz.chat.service.ChatMessageService;
import com.pz.chat.service.MemberService;
import com.pz.chat.vo.ChatTargetOptionResVo;
import com.pz.chat.vo.UserInfoResVo;
import com.pz.gulimall.common.utils.R;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("chatMessageServiceImpl")
public class ChatMessageServiceImpl extends ServiceImpl<ChatMessageDao, ChatMessageEntity> implements ChatMessageService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private MemberService memberService;

    /**
     * {userId} 获取来自 {targetId} 的未读消息
     * @param userId 用户唯一标识
     */
    @Override
    public List<ChatMessageEntity> getOffLineMsg(String userId, String targetId) {
        return list(new QueryWrapper<ChatMessageEntity>()
                .eq("from_id", targetId)
                .and(q -> q.eq("to_id", userId))
                .and(q -> q.eq("status", 0))
                .orderByAsc("send_time")
        );
    }

    /**
     * 获取所有与 userId 有关的消息
     * @param userId
     * @return
     */
    @Override
    public List<ChatMessageEntity> getAllMsg(String userId) {
        return list(new QueryWrapper<ChatMessageEntity>()
                .eq("from_id", userId)
                .or().eq("to_id", userId)
                .orderByAsc("send_time")
        );
    }

    /**
     * 获取自己可选的聊天记录
     * @param userId 自己的ID
     */
    @Override
    public List<ChatTargetOptionResVo> getAllMsgGroupByToId(String userId) {
        List<ChatMessageEntity> allMsg = getAllMsg(userId); //fromId、toId 必有一个是{userId}
        //过滤掉好友请求信息
        allMsg = allMsg.stream().filter(item -> item.getType() != 5).collect(Collectors.toList());
        Set<String> targetIds = new HashSet<>(); //搜集聊天对象的ID
        List<ChatTargetOptionResVo> ans = new ArrayList<>();
        allMsg.forEach(item -> {
            targetIds.add(item.getFromId());
            targetIds.add(item.getToId());
        });
        targetIds.remove(userId);
        for (String targetId : targetIds) {
            ChatTargetOptionResVo temp = new ChatTargetOptionResVo();
            temp.setTargetId(targetId);
            MemberEntity targetMember = memberService.getById(targetId);
            BeanUtils.copyProperties(targetMember, temp);
            // 获取未读消息数量
            List<ChatMessageEntity> offLineMsgs = getOffLineMsg(userId, targetId);
            temp.setUnReadNum(offLineMsgs.size());

            //获取最新消息
            ChatMessageEntity one = getOne(new QueryWrapper<ChatMessageEntity>()
                    .eq("from_id", targetId).and(q -> q.eq("to_id", userId))
                    .or()
                    .eq("from_id", userId).and(q -> q.eq("to_id", targetId))
                    .orderByDesc("send_time")
                    .last("LIMIT 1")
            );
            temp.setMsgId(one.getMsgId());
            temp.setLastMsg(one.getMsgContent());
            ans.add(temp);
        }
        return ans;
    }

    /**
     * 用户{userId}确认收到{targetId}的所有消息
     * @param userId 聊天主观用户ID
     * @param targetId 聊天对象ID
     */
    @Override
    public void ackTargetMsgs(String userId, String targetId) {
        // 获取来自 {targetId} 的所有未读消息
        List<ChatMessageEntity> list = list(new QueryWrapper<ChatMessageEntity>()
                .eq("from_id", targetId)
                .and(q -> q.eq("to_id", userId))
                .and(q -> q.eq("status", 0))
        );
        list.forEach(item -> {
            item.setType(MessageTypeEnum.CLIENT_ACK_MSG.getType());
            rabbitTemplate.convertAndSend(RabbitMqConstant.chatMsgExchange, RabbitMqConstant.chatMsgRoutingKey, item);
        });
    }

    @Override
    public R getChatTargetInfo(Map<String, Object> params) {
        String fromId = (String) params.get("fromId");
        String toId = (String) params.get("toId");
        if(!StringUtils.isEmpty(fromId) && !StringUtils.isEmpty(toId)) {
            JSONObject res = new JSONObject();
            UserInfoResVo vo = new UserInfoResVo();
            MemberEntity one = memberService.getOne(new QueryWrapper<MemberEntity>().eq("id", toId));
            BeanUtils.copyProperties(one, vo);
            List<ChatMessageEntity> chatMsgs = this.list(new QueryWrapper<ChatMessageEntity>()
                    .eq("from_id", fromId).and(q -> q.eq("to_id", toId))
                    .or()
                    .eq("from_id", toId).and(q -> q.eq("to_id", fromId))
                    .orderByAsc("send_time")
            );
            res.put("userInfo", vo);
            res.put("chatMsgList", chatMsgs);
            return R.okData(res);
        } else {
            return R.error("非法参数");
        }
    }
}
